package com.mall.security

import com.mall.util.JwtUtil
import jakarta.servlet.FilterChain
import jakarta.servlet.ServletException
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.stereotype.Component
import org.springframework.util.StringUtils
import org.springframework.web.filter.OncePerRequestFilter

import java.io.IOException
import java.util.Collections

/**
 * JWT认证过滤器
 * 
 * 该过滤器负责处理每个HTTP请求中的JWT令牌认证，主要功能包括：
 * 1. 从请求头中提取JWT令牌
 * 2. 验证令牌的有效性
 * 3. 解析令牌中的用户信息
 * 4. 设置Spring Security的认证上下文
 * 
 * @property jwtUtil JWT工具类，用于令牌的验证和解析
 */
@Component
class JwtAuthenticationFilter(private val jwtUtil: JwtUtil) : OncePerRequestFilter() {

    /**
     * 处理HTTP请求的过滤器方法
     * 
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @param filterChain 过滤器链
     * 
     * 处理流程：
     * 1. 从请求头中获取Bearer Token
     * 2. 验证Token的有效性
     * 3. 从Token中提取用户ID和用户名
     * 4. 创建认证对象并设置到SecurityContext中
     * 5. 继续处理请求
     */
    @Throws(ServletException::class, IOException::class)
    override fun doFilterInternal(
        request: HttpServletRequest,
        response: HttpServletResponse,
        filterChain: FilterChain
    ) {
        // 从请求头中获取JWT令牌
        val token = getTokenFromRequest(request)
        
        // 验证令牌是否有效
        if (StringUtils.hasText(token) && jwtUtil.validateToken(token)) {
            // 从令牌中获取用户信息
            val userId = jwtUtil.getIdFromToken(token)
            val username = jwtUtil.getUsernameFromToken(token)
            
            // 创建认证对象并设置到安全上下文中
            val authentication = UsernamePasswordAuthenticationToken(
                username, null, Collections.singletonList(SimpleGrantedAuthority("ROLE_ADMIN"))
            )
            
            SecurityContextHolder.getContext().authentication = authentication
        }
        
        filterChain.doFilter(request, response)
    }
    
    /**
     * 从请求头中提取JWT令牌
     * 
     * @param request HTTP请求对象
     * @return 提取到的JWT令牌字符串，如果没有找到则返回null
     * 
     * 提取规则：
     * 1. 从Authorization请求头中获取Bearer Token
     * 2. 验证Token是否以"Bearer "开头
     * 3. 去除"Bearer "前缀，返回实际的Token字符串
     */
    private fun getTokenFromRequest(request: HttpServletRequest): String? {
        val bearerToken = request.getHeader("Authorization")
        return if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            bearerToken.substring(7)
        } else null
    }
}